#include "ClientUdp.hpp"
#include "Comm.hpp"
#include <thread>
#include <string.h>

//./client_udp serverip serverport
int socketfd = -1;

void *run(void *args)
{
    while (true)
    {
        // 客户端接受服务器返回的数据
        char buffer[1024];
        struct sockaddr_in re;
        socklen_t rlen;
        
        ssize_t n = ::recvfrom(socketfd, buffer, sizeof(buffer), 0, CONV(&re), &rlen);
        if (n > 0)
        {
            buffer[n] = 0;
            std::cerr << buffer << std::endl;
        }
    }
    return nullptr;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cerr << "Usage error, Please use : ./client_udp serverip serverport" << std::endl;
        exit(3);
    }

    std::string ip = argv[1];
    std::uint16_t port = std::stoi(argv[2]);
    
    socketfd = ::socket(AF_INET, SOCK_DGRAM, 0);

    if (socketfd < 0)
    {
        LOG(LogLevel::FATAL) << "socket error";
        exit(1);
    }
    LOG(LogLevel::DEBUG) << "fd is " << socketfd;
    // 客户端需不需要bind呢？ 不需要
    // 客户端操作系统会自己动态分配一个没有被用过的端口号。
    /*
        我们知道一个端口号只能有标识一个进程，但是一个进程可以被多个端口号来标识，如果用户自己给定的一个端口号跟系统中已经存在的进程相互冲突，
        那么就会导致有一个进程用不了!! ，加入我们打开QQ抖音就不能用了？一般在公司当中，端口是需要申请的，申请了才可以使用
    */
    struct sockaddr_in server;
    memset(&server,0,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = ::inet_addr(ip.c_str());
    server.sin_port = ::htons(port);
    socklen_t len = sizeof(server);

    pthread_t tid;
    pthread_create(&tid, nullptr, run, nullptr);

    while (true)
    {
        std::string message;
        std::cout << "Please Enter# ";
        fflush(stdout);
        std::getline(std::cin, message);

        ssize_t sn = ::sendto(socketfd, message.c_str(), message.size(), 0, CONV(&server), len);
    }

    return 0;
}